//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.ServiceModel;
using System.Reflection;
using System.ServiceModel.Description;
using System.Collections.Generic;
using FinPlusConnService;
using FinPlusAssembler;
using FinPlusBaseCore;
using FinPlusInterfaces;

namespace FinPlusConnHost
{
    public class Program
    {
        private static Env _env;

        static void Main()
        {
            try
            {
                var path = Assembly.GetExecutingAssembly().ConfigPath();
                var config = path.ConfigXml(out _env);
                var conn = config["connections"];

                using (ServiceHost host = new ServiceHost(typeof(FinPlusServices), new Uri(conn["baseaddress"])))
                {
                    var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
                    if (smb == null)  
                        host.Description.Behaviors.Add(new ServiceMetadataBehavior());
                    
                    host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
                    //host.AddServiceEndpoint(typeof(IPodService), new NetTcpBinding(), conn["endaddress"]);
                   
                    var binding = GetBinding(conn);

                    host.AddServiceEndpoint(typeof(IFinPlusServices), binding, conn["endaddress"]);
                    AddDebug(host);

                    var throttle = GetThrottle(conn);
                    host.Description.Behaviors.Add(throttle);

                    host.CloseTimeout = TimeSpan.FromHours(double.Parse(conn["closetimeout"]));
                    host.OpenTimeout = TimeSpan.FromHours(double.Parse(conn["opentimeout"]));
                    host.Open();

                    Console.WriteLine("Press <Enter> to stop the service.");
                    Console.ReadLine();
                    host.Close();
                }
            }
            catch (ViewLoadException e)
            {
                Level.Error.Log(e.Message, e);
            }
        }

        private static NetTcpBinding GetBinding(IDictionary<string, string> conn)
        {
               return new NetTcpBinding()
                    {
                        ReceiveTimeout = TimeSpan.FromHours(double.Parse(conn["receivetimeout"].ToString())),
                        OpenTimeout = TimeSpan.FromHours(double.Parse(conn["opentimeout"])),
                        CloseTimeout = TimeSpan.FromHours(double.Parse(conn["closetimeout"])),
                        SendTimeout = TimeSpan.FromHours(double.Parse(conn["sendtimeout"]))
                    };
        }

        private static ServiceThrottlingBehavior GetThrottle(IDictionary<string, string> conn)
        {
            return new ServiceThrottlingBehavior()
            {
                MaxConcurrentCalls = int.Parse(conn["maxconcurrentcalls"]),
                MaxConcurrentSessions = int.Parse(conn["maxconcurrentsessions"]),
                MaxConcurrentInstances = int.Parse(conn["maxconcurrentinstances"])
            };
        }

        private static void AddDebug(ServiceHost host)
        {
                              
            var debug = host.Description.Behaviors.Find<ServiceDebugBehavior>();
            if (debug == null)
                host.Description.Behaviors.Add(new ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true });
            else if (!debug.IncludeExceptionDetailInFaults)
                debug.IncludeExceptionDetailInFaults = true;

        }
    }
}


